package org.redis.cluster.loadbalance.routing;

import java.util.Collection;

import org.redis.cluster.RedisCluster;
import org.redis.cluster.config.ClientConfig;
import org.redis.cluster.extension.ExtensionLoader;
import org.redis.cluster.loadbalance.LoadBalance;
import org.redis.cluster.plugin.Plugin;
import org.redis.cluster.redis.RedisCommand;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class RoutingLoadBalance implements LoadBalance,Plugin {
	
	private final static String LOAD_BALANCE="defaultLoadBalance";
	
	protected final Logger logger=LoggerFactory.getLogger(getClass());
	
	private RedisCluster redisCluster;
	private ExtensionLoader extensionLoader;
	private LoadBalance loadBalance;
	private RoutingManager routingManager; 
	
	@Override
	public void init(RedisCluster redisCluster) {
		this.redisCluster=redisCluster;
		this.extensionLoader=redisCluster.getExtensionLoader();
		this.loadBalance=initLoadBalance();
		this.routingManager=initRoutingManager();
	}
	
	protected LoadBalance initLoadBalance() {
		return extensionLoader.load(LOAD_BALANCE,LoadBalance.class);
	}
	
	protected RoutingManager initRoutingManager() {
		return new RoutingManager(redisCluster);
	}

	@Override
	public void destroy() {
	}
	
	@Override
	public ClientConfig select(Collection<ClientConfig> configs, RedisCommand command) {
		ClientConfig source=loadBalance.select(configs, command);
		if(source==null) {
			return null;
		}
		
		ClientConfig routing=routingManager.getRouting(source,command);
		if(routing==null) {
			if(logger.isDebugEnabled()) {
				logger.debug("没有找到路由,使用 {}",source);
			}
			
			return source;
		}
		
		if(logger.isDebugEnabled()) {
			if(!source.equals(routing)) {
				if(logger.isDebugEnabled()) {
					logger.debug("找到路由,使用 {} -> {}",source,routing);
				}
			}
		}
		
		return routing;
	}
	
	public void setLoadBalance(LoadBalance loadBalance) {
		this.loadBalance = loadBalance;
	}
	public LoadBalance getLoadBalance() {
		return loadBalance;
	}
}